package com.bjbn.service.impl;

import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.search.TotalHits;
import co.elastic.clients.elasticsearch.core.search.TotalHitsRelation;
import com.bjbn.config.ElasticsearchIndexNameResolver;
import com.bjbn.entity.EsDeviceValueThs;
import com.bjbn.entity.EsDeviceValueLx;
import com.bjbn.service.ElasticsearchService;
import lombok.extern.slf4j.Slf4j;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.BulkRequest;
import co.elastic.clients.elasticsearch.core.BulkResponse;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.json.JsonData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * Elasticsearch服务实现类
 */
@Slf4j
@Service
public class ElasticsearchServiceImpl implements ElasticsearchService {

    @Autowired
    private ElasticsearchClient elasticsearchClient;

    @Autowired
    private ElasticsearchIndexNameResolver indexNameResolver;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean saveThsData(EsDeviceValueThs data) {
        try {
            // 生成文档ID
            if (data.getId() == null) {
                data.setId(UUID.randomUUID().toString());
            }

            String indexName = indexNameResolver.resolveIndexName(null);

            elasticsearchClient.index(i -> i
                    .index(indexName)
                    .id(data.getId())
                    .document(data));

            log.info("成功保存温湿度传感器数据到ES，设备编号：{}，索引：{}", data.getDeviceNum(), indexName);
            return true;
        } catch (Exception e) {
            log.error("保存温湿度传感器数据到ES失败，设备编号：{}", data.getDeviceNum(), e);
            return false;
        }
    }

    @Override
    public boolean saveThsDataBatch(List<EsDeviceValueThs> dataList) {
        if (dataList == null || dataList.isEmpty()) {
            return true;
        }

        try {
            BulkRequest.Builder br = new BulkRequest.Builder();

            for (EsDeviceValueThs data : dataList) {
                if (data.getId() == null) {
                    data.setId(UUID.randomUUID().toString());
                }

                String indexName = indexNameResolver.resolveIndexName(null);

                br.operations(op -> op
                        .index(idx -> idx
                                .index(indexName)
                                .id(data.getId())
                                .document(data)));
            }

            BulkResponse result = elasticsearchClient.bulk(br.build());

            if (result.errors()) {
                log.error("批量保存温湿度传感器数据到ES失败，存在错误");
                return false;
            }

            log.info("成功批量保存{}条温湿度传感器数据到ES", dataList.size());
            return true;
        } catch (Exception e) {
            log.error("批量保存温湿度传感器数据到ES失败", e);
            return false;
        }
    }

    @Override
    public boolean saveLxData(EsDeviceValueLx data) {
        try {
            // 生成文档ID
            if (data.getId() == null) {
                data.setId(UUID.randomUUID().toString());
            }

            String indexName = indexNameResolver.resolveIndexName(null);

            elasticsearchClient.index(i -> i
                    .index(indexName)
                    .id(data.getId())
                    .document(data));

            log.info("成功保存照度传感器数据到ES，设备编号：{}，索引：{}", data.getDeviceNum(), indexName);
            return true;
        } catch (Exception e) {
            log.error("保存照度传感器数据到ES失败，设备编号：{}", data.getDeviceNum(), e);
            return false;
        }
    }

    @Override
    public boolean saveLxDataBatch(List<EsDeviceValueLx> dataList) {
        if (dataList == null || dataList.isEmpty()) {
            return true;
        }

        try {
            BulkRequest.Builder br = new BulkRequest.Builder();

            for (EsDeviceValueLx data : dataList) {
                if (data.getId() == null) {
                    data.setId(UUID.randomUUID().toString());
                }

                String indexName = indexNameResolver.resolveIndexName(null);

                br.operations(op -> op
                        .index(idx -> idx
                                .index(indexName)
                                .id(data.getId())
                                .document(data)));
            }

            BulkResponse result = elasticsearchClient.bulk(br.build());

            if (result.errors()) {
                log.error("批量保存照度传感器数据到ES失败，存在错误");
                return false;
            }

            log.info("成功批量保存{}条照度传感器数据到ES", dataList.size());
            return true;
        } catch (Exception e) {
            log.error("批量保存照度传感器数据到ES失败", e);
            return false;
        }
    }

    @Override
    public List<EsDeviceValueThs> queryThsDataByDeviceNum(String deviceNum, String startTime, String endTime) {
        List<EsDeviceValueThs> result = new ArrayList<>();

        try {
            String indexName = indexNameResolver.resolveIndexName(null);


            SearchResponse<EsDeviceValueThs> response = elasticsearchClient.search(s -> s
                    .index(indexName)
                    .query(q -> q
                            .bool(b -> b
                                    .must(m -> m.term(t -> t.field("deviceNum").value(deviceNum)))
                            ))
                    .size(1000), EsDeviceValueThs.class);

            for (Hit<EsDeviceValueThs> hit : response.hits().hits()) {
                result.add(hit.source());
            }

            log.info("查询温湿度传感器数据成功，设备编号：{}，返回{}条记录", deviceNum, result.size());
        } catch (Exception e) {
            log.error("查询温湿度传感器数据失败，设备编号：{}", deviceNum, e);
        }

        return result;
    }

    @Override
    public List<EsDeviceValueLx> queryLxDataByDeviceNum(String deviceNum, String startTime, String endTime) {
        List<EsDeviceValueLx> result = new ArrayList<>();

        try {
            String indexName = indexNameResolver.resolveIndexName(deviceNum);

            SearchResponse<EsDeviceValueLx> response = elasticsearchClient.search(s -> s
                    .index(indexName)
                    .query(q -> q
                            .bool(b -> b
                                    .must(m -> m.term(t -> t.field("deviceNum").value(deviceNum)))
                            ))
                    .size(1000), EsDeviceValueLx.class);

            for (Hit<EsDeviceValueLx> hit : response.hits().hits()) {
                result.add(hit.source());
            }

            log.info("查询照度传感器数据成功，设备编号：{}，返回{}条记录", deviceNum, result.size());
        } catch (Exception e) {
            log.error("查询照度传感器数据失败，设备编号：{}", deviceNum, e);
        }

        return result;
    }
} 